using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;

namespace ProxyServer.Certs;

public class ServiceCertStoreOptions
{
    public string Root { get; set; } = "./certs";
}

public static class ServivceCertStoreExtensions
{
    public static IServiceCollection AddServiceCertStore(this IServiceCollection services)
    {
        services.AddOptions<ServiceCertStoreOptions>()
            .Configure((ServiceCertStoreOptions options, IServiceProvider sp) =>
            {
                sp.GetService<IConfiguration>()?.GetSection(nameof(SerivceCertStore))?.Bind(options);
            });

        services.AddSingleton<SerivceCertStore>();

        return services;
    }
}

public interface IServiceCertStore
{

}

public class SerivceCertStore : IServiceCertStore
{
    private readonly ILogger _logger;
    private readonly DirectoryInfo? _dir;
    private readonly ConcurrentDictionary<Guid, X509Certificate2> _certs = new ConcurrentDictionary<Guid, X509Certificate2>();

    public SerivceCertStore(IOptions<ServiceCertStoreOptions> options, ILogger<SerivceCertStore> logger)
    {
        _logger = logger;
        _dir = CheckDirectory(options.Value, logger);
    }

    private static DirectoryInfo? CheckDirectory(ServiceCertStoreOptions value, ILogger logger)
    {
        var dir = Directory.Exists(value.Root)
            ? new DirectoryInfo(value.Root)
            : Directory.CreateDirectory(value.Root);

        logger.LogInformation("Service Certificate Store: {Path}", dir?.FullName);

        return dir;
    }

    public Task<X509Certificate2> GetCertificateAsync(Guid serviceId, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    private X509Store CreateX509Store()
    {
        return new X509Store(StoreName.My, StoreLocation.CurrentUser);
    }

    private string GetFileName(Guid serviceId)
    {
        return serviceId.ToString("N");
    }

    [MemberNotNull("_dir")]
    private void ThrowIfDirectoryNotExists()
    {
        if (_dir is null)
        {
            throw new InvalidOperationException("Service Certificate Directory not exists");
        }
    }
}